package com.asm.otherUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CpkTool {

        /**
         * 计算统计数据，包括 Max, Min, Mean, Sigma, Cpk
         * @param data 数据数组
         * @param upperLimit 上规格限
         * @param lowerLimit 下规格限
         */
        public static void calculateStats(double[] data, double upperLimit, double lowerLimit) {
            // 第一步：检查数据是否为空
            if (data == null || data.length == 0) {
                System.out.println("数据为空，无法计算。");
                return;
            }

            // 第二步：计算最大值和最小值
            double max = Arrays.stream(data).max().orElse(Double.NaN);
            double min = Arrays.stream(data).min().orElse(Double.NaN);

            // 第三步：计算平均值（Mean）
            double mean = Arrays.stream(data).average().orElse(Double.NaN);

            // 第四步：计算标准差（Sigma）
            double sumSquaredDiffs = Arrays.stream(data).map(x -> Math.pow(x - mean, 2)).sum();
            double sigma = Math.sqrt(sumSquaredDiffs / (data.length - 1)); // 使用样本标准差公式

            // 第五步：计算 Cpk
            double cpkLower = (mean - lowerLimit) / (3 * sigma); // 下限 Cpk
            double cpkUpper = (upperLimit - mean) / (3 * sigma); // 上限 Cpk
            double cpk = Math.min(cpkLower, cpkUpper);           // 取较小值为 Cpk

            // 第六步：输出结果  Max   Min   Mean  Sigma  Cpk
            System.out.printf("Max: %.3f\n", max);
            System.out.printf("Min: %.3f\n", min);
            System.out.printf("Mean: %.3f\n", mean);
            System.out.printf("Sigma: %.3f\n", sigma);
            System.out.printf("Cpk: %.3f\n", cpk);

            // 第七步：生成真实数据的正态分布曲线
            generateNormalDistribution(mean, sigma, min, max);

            // 第八步：生成理想正态分布曲线
            generateIdealNormalDistribution(lowerLimit, upperLimit);
        }

        /**
         * 生成真实正态分布曲线的数据并输出 x 和 y 坐标
         * @param mean 平均值
         * @param sigma 标准差
         * @param minX x 轴的最小值
         * @param maxX x 轴的最大值
         */
        public static void generateNormalDistribution(double mean, double sigma, double minX, double maxX) {
            System.out.println("\n真实正态分布曲线数据：");

            int numPoints = 100; // 定义生成的点数
            double step = (maxX - minX) / numPoints; // 定义步长
            List<Double> xList = new ArrayList<>();
            List<Double> yList = new ArrayList<>();

            for (int i = 0; i <= numPoints; i++) {
                double x = minX + i * step; // 计算 x 值
                double y = (1 / (sigma * Math.sqrt(2 * Math.PI))) * Math.exp(-Math.pow(x - mean, 2) / (2 * Math.pow(sigma, 2))); // 计算正态分布的 y 值
                xList.add(x);
                yList.add(y);
            }

            System.out.println("x轴数据 (真实正态分布): " + xList);
            System.out.println("y轴数据 (真实正态分布): " + yList);
        }

        /**
         * 生成理想正态分布曲线的数据并输出 x 和 y 坐标
         * @param lowerLimit 下规格限
         * @param upperLimit 上规格限
         */
        public static void generateIdealNormalDistribution(double lowerLimit, double upperLimit) {
            System.out.println("\n理想正态分布曲线数据：");

            // 计算理想均值和标准差
            double idealMean = (lowerLimit + upperLimit) / 2; // 均值为上下限的中点
            double idealSigma = (upperLimit - lowerLimit) / 6; // 标准差为上下限差值的1/6

            int numPoints = 200; // 定义生成的点数
            double step = (upperLimit - lowerLimit) / numPoints; // 定义步长
            List<Double> xList = new ArrayList<>();
            List<Double> yList = new ArrayList<>();

            for (int i = 0; i <= numPoints; i++) {
                double x = lowerLimit + i * step; // 计算 x 值
                double y = (1 / (idealSigma * Math.sqrt(2 * Math.PI))) * Math.exp(-Math.pow(x - idealMean, 2) / (2 * Math.pow(idealSigma, 2))); // 计算正态分布的 y 值
                xList.add(x);
                yList.add(y);
            }

            System.out.println("x轴数据 (理想正态分布): " + xList);
            System.out.println("y轴数据 (理想正态分布): " + yList);
        }

        public static void main(String[] args) {
            // 示例数据
            double[] data = {
                    0.665,
                    0.664,
                    0.659,
                    0.658,
                    0.652,
                    0.648,
                    0.647,
                    0.637,
                    0.635
            };/*       double[] data = {


0.675,
0.673,
0.667,
0.659,
0.656,0.656,
0.655,
0.653,
0.652,
0.651,
0.650,0.650,
0.649,0.649,
0.645,0.645,
0.644,
0.639,0.639,0.639,
            };*/
            double upperLimit = 0.66; // 上规格限
            double lowerLimit = 0.65; // 下规格限

            // 调用计算方法
            calculateStats(data, upperLimit, lowerLimit);
        }
}
